package com.googlecode.perfectable.eventable.routing;

import java.lang.ref.WeakReference;

class WeakSinkWrapper<M> implements Sink<M> {
	public final WeakReference<Sink<M>> sinkReference;

	public Source<M> attached;

	public static <M> void attach(Source<M> source, Sink<M> sink) {
		WeakReference<Sink<M>> sinkReference = new WeakReference<>(sink);
		WeakSinkWrapper<M> wrapper = new WeakSinkWrapper<>(sinkReference);
		wrapper.attach(source);
	}

	private WeakSinkWrapper(WeakReference<Sink<M>> sinkReference) {
		this.sinkReference = sinkReference;
	}

	private void attach(Source<M> source) {
		this.attached = source;
		source.listen(this);
	}

	private void detach() {
		this.attached.stop(this);
		this.attached = null;
	}

	@Override
	public void receive(M event) {
		final Sink<M> sink = this.sinkReference.get();
		if(sink == null) {
			this.detach();
			return;
		}
		sink.receive(event);
	}

}
